/**
1.vm是selfVue本身
2.exp是监听的key的名称
3.callback是当数据变化时调用的更新方法
**/
/**
watcher的职责主要是作为当更新，当observer监听到更新之后，通过调用Dep容器的notify方法，循环去取执行watcher的update方法，现在来对watcher的细节进行回顾
1.Watcher构造器的参数有vm,就是SelfVue实例，作为给callback执行时的作用域，反过来说callback的作用域是SelfVue的实例 (javascript作为函数型语言，
  什么都可以作为参数传递，function,object,说白了，其实function也是Object)。
2.在Watcher构造函数中，将变量名为exp对应的值作为this.val的值，用作后面新值变化时来做对比,this.val的赋值是调用的this.prototype.get()方法，其中将Dep.target的值
设置为this当前对象，接下来执行this.vm.data[this.exp]方法，这样会触发Object.defineProperty定义的get方法，Dep.target不为空，将此watcher加入到Dep容器管理的
订阅器中。之后再将Dep.target设置为null,这样再执行defineProperty的get方法就不会再将此订阅器加入容器中。
3.update作为run方法的包装方法。
4.run方法里面执行的是真正的更新方法，通过this.vm.data[exp]去拿到现在exp被新赋予的值,this.val对应的是之前exp对应的旧值，如果不相等，
则以call的方式执行callback方法，指定callback作用域为vm, exp对应的新值与旧值都作为callback的参数。

**/

function Watcher(vm, exp, callback) {
  this.vm = vm
  this.exp = exp
  this.callback = callback
  this.val = this.get() //旧值
}

Watcher.prototype = {
  update: function() {
    this.run()
  },
  run: function() {
    var val = this.vm.data[this.exp] //这里获取是key 为exp值的新值
    var oldVal = this.val //之前初始化watcher时的旧值
    if (oldVal !== val) {
      this.val = val //将新值赋给this.val,下次再次对比
      this.callback.call(this.vm, val, oldVal) //新值不等于旧值，执行callback函数，指定callback作用域为vm
    }
  },
  get: function() {
    Dep.target = this
    var val = this.vm.data[this.exp]
    Dep.target = null
    return val
  }
}